`timescale 1ns /100ps

module mem(dataIn, dataOut, clk, we, addr);
	input clk,we;
	input [6:0] addr;
	input [7:0] dataIn;
	output [7:0] dataOut;
	
	wire [7:0] dataOut;
	
	reg [7:0] core[127:0];
	
	always @(posedge clk)
		if (we) core[addr] <= dataIn;
	
	assign dataOut = core[addr];
	
endmodule

module data(dataIn, dataOut, clk, we, addr, size, bt, error);
	input clk,we;
	input [6:0] addr;
	input [1:0] size;
	input [2:0] bt;
	input [63:0] dataIn;
	output [63:0] dataOut;
	output [1:0] error;
	
	wire [7:0] dataIn0, dataIn1, dataIn2, dataIn3, dataIn4, dataIn5, dataIn6, dataIn7;
	wire [7:0] dataOut0, dataOut1, dataOut2, dataOut3, dataOut4, dataOut5, dataOut6, dataOut7;
	reg we0, we1, we2, we3, we4, we5, we6, we7;
	wire [2:0] bt;
	
	reg [1:0] error;
	reg [63:0] dataOut;
	
	mem mem0(dataIn0, dataOut0, clk, we0, addr);
	mem mem1(dataIn1, dataOut1, clk, we1, addr);
	mem mem2(dataIn2, dataOut2, clk, we2, addr);
	mem mem3(dataIn3, dataOut3, clk, we3, addr);
	mem mem4(dataIn4, dataOut4, clk, we4, addr);
	mem mem5(dataIn5, dataOut5, clk, we5, addr);
	mem mem6(dataIn6, dataOut6, clk, we6, addr);
	mem mem7(dataIn7, dataOut7, clk, we7, addr);
	
	assign dataIn0 = dataIn[7:0];
	assign dataIn1 = dataIn[15:8];
	assign dataIn2 = dataIn[23:16];
	assign dataIn3 = dataIn[31:24];
	assign dataIn4 = dataIn[39:32];
	assign dataIn5 = dataIn[47:40];
	assign dataIn6 = dataIn[55:48];
	assign dataIn7 = dataIn[63:56];
	
	initial	
		begin
			error = 0;			
		end
	
	always @(*)
		begin
			if(we)
				begin
					case(size)
						0: begin 
								we0 = we;
								we1 = we;
								we2 = we;
								we3 = we;
								we4 = we;
								we5 = we;
								we6 = we;
								we7 = we;
								dataOut = {dataOut7,dataOut6,dataOut5,dataOut4,dataOut3,dataOut2,dataOut1,dataOut0};
							end 
						1: begin 
								we0 = we && (bt == 0);
								we1 = we && (bt == 1);
								we2 = we && (bt == 2);
								we3 = we && (bt == 3);
								we4 = we && (bt == 4);
								we5 = we && (bt == 5);
								we6 = we && (bt == 6);
								we7 = we && (bt == 7);
								case(bt)
									0: dataOut = {56'b0,dataOut0};
									1: dataOut = {56'b0,dataOut1};
									2: dataOut = {56'b0,dataOut2};
									3: dataOut = {56'b0,dataOut3};
									4: dataOut = {56'b0,dataOut4};
									5: dataOut = {56'b0,dataOut5};
									6: dataOut = {56'b0,dataOut6};
									7: dataOut = {56'b0,dataOut7};
								endcase
							end
						2:  begin  
								we0 = we && (bt == 0);
								we1 = we && (bt == 0);
								we2 = we && (bt == 2);
								we3 = we && (bt == 2);
								we4 = we && (bt == 4);
								we5 = we && (bt == 4);
								we6 = we && (bt == 6);
								we7 = we && (bt == 6);
								case(bt)
									0: dataOut = {48'b0,dataOut1,dataOut0};
									2: dataOut = {48'b0,dataOut3,dataOut2};
									4: dataOut = {48'b0,dataOut5,dataOut4};
									6: dataOut = {48'b0,dataOut7,dataOut6};
									default: error[0] = 1;
								endcase
							end
						3:	 begin  
								we0 = we && (bt == 0);
								we1 = we && (bt == 0);
								we2 = we && (bt == 0);
								we3 = we && (bt == 0);
								we4 = we && (bt == 4);
								we5 = we && (bt == 4);
								we6 = we && (bt == 4);
								we7 = we && (bt == 4);
								case(bt)
									0: dataOut = {32'b0,dataOut3,dataOut2,dataOut1,dataOut0};
									4: dataOut = {32'b0,dataOut7,dataOut6,dataOut5,dataOut4};
									default: error[0]=1;
								endcase
							end
					endcase 
				end
		end
	
endmodule